import 'package:built_collection/built_collection.dart';
import 'package:dartz/dartz.dart';
import 'package:equatable/equatable.dart';
import 'package:website.core/core/domain/entities/web/web_payment_method.dart';
import 'package:website.core/core/domain/errors/failures.dart';
import 'package:website.core/core/domain/repositories/web_payment_method_repository/repository.dart';
import 'package:website.core/core/domain/utils/either_extension.dart';

part 'failures.dart';

part 'result.dart';

abstract class GetPaymentMethodData {
  Future<Either<PaymentMethodDataGettingFailure, PaymentMethodDataGettingResult>> call();
}

class GetPaymentMethodDataImpl implements GetPaymentMethodData {
  const GetPaymentMethodDataImpl({
    required WebPaymentMethodRepository webPaymentMethodRepository,
  }) : _webPaymentMethodRepository = webPaymentMethodRepository;

  final WebPaymentMethodRepository _webPaymentMethodRepository;

  @override
  Future<Either<PaymentMethodDataGettingFailure, PaymentMethodDataGettingResult>> call() async {
    final failureOrSavedPaymentMethodGettingResult =
        await _webPaymentMethodRepository.getSavedPaymentMethods();

    if (failureOrSavedPaymentMethodGettingResult.isLeft()) {
      final savedPaymentMethodGettingFailure = failureOrSavedPaymentMethodGettingResult.asLeft();

      if (savedPaymentMethodGettingFailure is UnauthorizedWebSavedPaymentMethodGettingFailure) {
        const failure = UnauthorizedPaymentMethodDataGettingFailure();
        return left(failure);
      }

      if (savedPaymentMethodGettingFailure is ServerWebSavedPaymentMethodGettingFailure) {
        const failure = ServerPaymentMethodDataGettingFailure();
        return left(failure);
      }

      if (savedPaymentMethodGettingFailure is NetworkWebSavedPaymentMethodGettingFailure) {
        const failure = NetworkPaymentMethodDataGettingFailure();
        return left(failure);
      }

      throw UnimplementedError();
    }

    final savedPaymentMethodGettingResult = failureOrSavedPaymentMethodGettingResult.asRight();

    final result = PaymentMethodDataGettingResult(
      webSavedPaymentMethods: savedPaymentMethodGettingResult.savedPaymentMethods,
    );

    return right(result);
  }
}
